/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package colordrips;

import java.util.ArrayList;

/**
 * Classe que conterá todos os métodos (estáticos) de lógica do jogo.
 * @author SimaoItalo
 */
public class GameLogic {
    
    /**
     * Verifica se ainda é possível realizar uma jogada.
     * @param matrixBlocks - Matriz principal de labels que é criada no campo de jogo.
     * @return - Retorna TRUE caso ainda haja jogadas possíveis.
     */
    public static boolean hasPossibleMoves(ArrayList<ArrayList<Block>> matrixBlocks){
        int count = 0;
        for(int i = 1; i < 7; i++){
            for(int j = 1; j < 11; j++){
                if(isAPossibleMove(matrixBlocks, matrixBlocks.get(i).get(j))){
                    count++;
                }
            }
        }
        if(count == 0){
            return false;
        } else{
            return true;
        }
    }
    
    /**
     * Verifica se o bloco selecionado é um movimento válido para jogada.
     * @param matrixBlocks - Matriz principal de labels que é criada no campo de jogo.
     * @param selectedBlock - Bloco que foi selecionado no campo de jogo.
     * @return - Retorna TRUE caso seja uma jogada válida.
     */
    public static boolean isAPossibleMove(ArrayList<ArrayList<Block>> matrixBlocks, Block selectedBlock){
        
        if((matrixBlocks.get(selectedBlock.getiPosition()+1).get(selectedBlock.getjPosition()).hasSameColor(selectedBlock))
        || (matrixBlocks.get(selectedBlock.getiPosition()-1).get(selectedBlock.getjPosition()).hasSameColor(selectedBlock))
        || (matrixBlocks.get(selectedBlock.getiPosition()).get(selectedBlock.getjPosition()+1).hasSameColor(selectedBlock))
        || (matrixBlocks.get(selectedBlock.getiPosition()).get(selectedBlock.getjPosition()-1).hasSameColor(selectedBlock))){
            return true;
        } else {
            return false;
        }
        
    }
    
    /**
     * Faz a remoção dos blocos que estão próximos ao bloco clicado no campo de jogo.
     * @param matrixBlocks - Matriz principal de labels que é criada no campo de jogo.
     * @param selectedBlock - Bloco que foi selecionado no campo de jogo. 
     */
    public static void removeBlocks(ArrayList<ArrayList<Block>> matrixBlocks, Block selectedBlock){
        if(matrixBlocks.get(selectedBlock.getiPosition()+1).get(selectedBlock.getjPosition()).hasSameColor(selectedBlock)){
            Block nextBlock = matrixBlocks.get(selectedBlock.getiPosition()+1).get(selectedBlock.getjPosition());
            removeThisBlock(nextBlock, selectedBlock, matrixBlocks);
        }
        if(matrixBlocks.get(selectedBlock.getiPosition()-1).get(selectedBlock.getjPosition()).hasSameColor(selectedBlock)){
            Block nextBlock = matrixBlocks.get(selectedBlock.getiPosition()-1).get(selectedBlock.getjPosition());
            removeThisBlock(nextBlock, selectedBlock, matrixBlocks);
        }
        if(matrixBlocks.get(selectedBlock.getiPosition()).get(selectedBlock.getjPosition()+1).hasSameColor(selectedBlock)){
            Block nextBlock = matrixBlocks.get(selectedBlock.getiPosition()).get(selectedBlock.getjPosition()+1);
            removeThisBlock(nextBlock, selectedBlock, matrixBlocks);
        }
        if(matrixBlocks.get(selectedBlock.getiPosition()).get(selectedBlock.getjPosition()-1).hasSameColor(selectedBlock)){
            Block nextBlock = matrixBlocks.get(selectedBlock.getiPosition()).get(selectedBlock.getjPosition()-1);
            removeThisBlock(nextBlock, selectedBlock, matrixBlocks);
        } 
    }
    
    /**
     * Faz a remoção de um único bloco, e chama novamente o método "removeBlocks" numa chamada recursiva.
     * @param matrixBlocks - Matriz principal de labels que é criada no campo de jogo.
     * @param selectedBlock - Bloco que foi selecionado no campo de jogo. 
     * @param nextBlock - Próximo bloco de mesma cor ao selectedBlock.
     */
    private static void removeThisBlock(Block nextBlock, Block selectedBlock, ArrayList<ArrayList<Block>> matrixBlocks){
        selectedBlock.clearBlock();
        removeBlocks(matrixBlocks, nextBlock);
        matrixBlocks.get(nextBlock.getiPosition()).get(nextBlock.getjPosition()).clearBlock();
    }
    
    /**
     * Tem como função verificar o número de peças que estão atualmente sendo
     * mostradas no campo de jogo.
     * @param matrixBlocks - Matriz principal de labels que é criada no campo de jogo.
     * @return - Número de blocos atualmente sendo mostradas no campo.
     */
    public static int checkNumberOfBlocks(ArrayList<ArrayList<Block>> matrixBlocks){
        int qtOfBlocks = 0;
        for(int i = 1; i < 7; i++){
            for(int j = 1; j < 11; j++){
                if(!matrixBlocks.get(i).get(j).isEmpty()){
                    qtOfBlocks++;
                }
            }
        }
        return qtOfBlocks;
    }
    
    /**
     * Faz o ajuste de linhas da matriz.
     * @param matrixBlocks - Matriz principal de labels que é criada no campo de jogo.
     */
    public static void adjustLines(ArrayList<ArrayList<Block>> matrixBlocks){
        // procura blocos vazios, que contém um bloco cheio acima, e então os troca
        for(int i = 1; i < 7; i++){
            for(int j = 1; j < 11; j++){
                if(matrixBlocks.get(i).get(j).isEmpty()){
                    if(!matrixBlocks.get(i-1).get(j).isEmpty()){
                        Block temp = matrixBlocks.get(i).get(j);
                        temp.setiPosition(i-1);
                        matrixBlocks.get(i-1).get(j).setiPosition(i);
                        matrixBlocks.get(i).set(j, matrixBlocks.get(i-1).get(j));
                        matrixBlocks.get(i-1).set(j, temp);
                        adjustLines(matrixBlocks);
                    }
                }
            }
        }
    }
    
    /**
     * Faz o ajuste de colunas da matriz.
     * @param matrixBlocks - Matriz principal de labels que é criada no campo de jogo.
     */
    public static void adjustColumns(ArrayList<ArrayList<Block>> matrixBlocks){
        for(int i = 1; i < 7; i++){
            for(int j = 1; j < 11; j++){
                if(matrixBlocks.get(i).get(j).isEmpty()){
                    if(!matrixBlocks.get(i).get(j+1).isEmpty()){
                        Block temp = matrixBlocks.get(i).get(j);
                        temp.setjPosition(j+1);
                        matrixBlocks.get(i).get(j+1).setjPosition(j);
                        matrixBlocks.get(i).set(j, matrixBlocks.get(i).get(j+1));
                        matrixBlocks.get(i).set(j+1, temp);
                        adjustColumns(matrixBlocks);
                    }
                }
            }
        }
//        int i = 6;
//        for(int j = 9; j > 0; j--){
//            if(matrixBlocks.get(i).get(j).isEmpty()){
//                for(int k = 1; k < 7; k++){
//                    Block temp = matrixBlocks.get(k).get(j);
//                    temp.setjPosition(j+1);
//                    matrixBlocks.get(k).get(j+1).setjPosition(j);
//                    matrixBlocks.get(k).set(j, matrixBlocks.get(k).get(j+1));
//                    matrixBlocks.get(k).set(j+1, temp);
//                }
//                adjustColumns(matrixBlocks);
//            }
//        }
    }
    
    /**
     * Seta as cores dos blocos vazios como "none"
     * @param matrixBlocks - Matriz principal de labels que é criada no campo de jogo.
     */
    public static void adjustColors(ArrayList<ArrayList<Block>> matrixBlocks){
        for(int i = 1; i < 7; i++){
            for(int j = 1; j < 11; j++){
                if(matrixBlocks.get(i).get(j).isEmpty()){
                    matrixBlocks.get(i).get(j).setColor("none");
                }
            }
        }
    }
    
}
